import { SetupContext, computed, defineComponent, ref } from "vue";
import { OrderPropsType, OrderedItem, orderProps } from "./order.props";
import FListView from '../../../components/list-view/src/list-view.component';
import FButton from '../../../components/button/src/button.component';
import FComboList from '../../../components/combo-list/src/combo-list.component';
import './order.scss';

export default defineComponent({
    name: 'FOrder',
    props: orderProps,
    emits: ['change'],
    setup(props: OrderPropsType, context: SetupContext) {
        const orderedValues = ref<OrderedItem[]>(props.items);
        const orderFieldText = ref('排序列');
        const orderTypeText = ref('排序方式');
        const addItemButtonText = ref('添加排序列');
        const sortTyes = [{ id: 'asc', name: '升序' }, { id: 'desc', name: '降序' }];
        const orderedFieldMap = ref<Map<string, boolean>>(new Map<string, boolean>());

        function updateOrderedFieldMap() {
            const orderedFieldArray = orderedValues.value.map<[string, boolean]>((item: OrderedItem) => {
                return [item.id, true];
            });
            orderedFieldMap.value = new Map<string, boolean>(orderedFieldArray);
        }

        updateOrderedFieldMap();

        const unOrderedFields = computed(() => {
            return props.dataSource.map((item: any) => {
                item.disabled = orderedFieldMap.value.has(item.id);
                return item;
            });
        });

        const orderClass = computed(() => {
            const classObject = {
                'f-order': true
            } as Record<string, boolean>;
            return classObject;
        });

        function onRemoveSelectionItem(removedItem: OrderedItem) {
            orderedValues.value = orderedValues.value.filter((item: OrderedItem) => item.id !== removedItem.id);
            updateOrderedFieldMap();
            context.emit('change', orderedValues.value);
        }

        function onClick() {
            orderedValues.value = [...orderedValues.value, { id: Date.now().toString(), name: '', order: 'asc' }];
            updateOrderedFieldMap();
            context.emit('change', orderedValues.value);
        }

        function onOrderedFieldChanged(items: any[]) {
            updateOrderedFieldMap();
            context.emit('change', orderedValues.value);
        }

        function onSortOrderChanged(items: any[]) {
            if (items && items.length) {
                const sortedItemMap = new Map<string, OrderedItem>();
                items.reduce((columnMap: Map<string, OrderedItem>, sortedItem: OrderedItem) => {
                    columnMap.set(sortedItem.id, sortedItem);
                    return columnMap;
                }, sortedItemMap);
                orderedValues.value = items.map((item: OrderedItem) => sortedItemMap.get(item.id) as OrderedItem);
                context.emit('change', orderedValues.value);
            }
        }

        function renderOrderList() {
            return <FListView style="flex:1" data={orderedValues.value} draggable={true} view="DraggableView" keep-order={true}
                itemClass="f-order-item" onRemoveItem={onRemoveSelectionItem} onChange={onSortOrderChanged}>{{
                    header: () => (
                        <div class="f-order-header">
                            <span class="f-order-header-order-field">{orderFieldText.value}</span>
                            <span class="f-order-header-order-type">{orderTypeText.value}</span>
                        </div>
                    ),
                    itemContent: (item: any) => {
                        return (
                            <div class="f-order-item-content">
                                <FComboList class="f-order-item-content-order-field" data={unOrderedFields.value}
                                    valueField="id" textField="name" idField="id" v-model={item.id}
                                    onChange={onOrderedFieldChanged}
                                    onClear={onOrderedFieldChanged}></FComboList>
                                <FComboList class="f-order-item-content-order-type" data={sortTyes}
                                    valueField="id" textField="name" idField="id" v-model={item.order}
                                    onChange={onOrderedFieldChanged}></FComboList>
                            </div>
                        );
                    },
                    footer: () => (
                        <div class="f-order-footer">
                            <FButton type="link" class="f-order-add-button" onClick={onClick}>{{
                                default: () => (<>
                                    <span class="f-order-add-icon">
                                        <i class="f-icon f-icon-add"></i>
                                    </span>
                                    {addItemButtonText.value}
                                </>)
                            }}</FButton>
                        </div>
                    )
                }}</FListView>;
        }

        return () => {
            return (
                <div class={orderClass.value}>
                    {renderOrderList()}
                </div>);
        };
    }
});
